package com.bwie.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.TbOrderDetailMapper;
import com.bwie.mapper.TbOrderRecordMapper;
import com.bwie.mapper.TbProdInfoMapper;
import com.bwie.poi.ExcelUtil;
import com.bwie.poi.StringUtils;
import com.bwie.poi.TbUser;
import com.bwie.pojo.*;
import com.bwie.service.IUserService;
import com.bwie.service.TbOrderService;
import com.bwie.mapper.TbOrderMapper;
import com.bwie.utils.R;
import com.bwie.vo.OrderDetailVo;
import com.bwie.vo.PageInfoVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
* @author Lenovo
* @description 针对表【tb_order(订单表)】的数据库操作Service实现
* @createDate 2025-07-21 19:43:21
*/
@Service
public class TbOrderServiceImpl extends ServiceImpl<TbOrderMapper, TbOrder>
    implements TbOrderService{

    @Autowired
    private TbOrderMapper tbOrderMapper;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private TbProdInfoMapper tbProdInfoMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private TbOrderDetailMapper tbOrderDetailMapper;

    @Autowired
    private TbOrderRecordMapper tbOrderRecordMapper;

    @Autowired
    private IUserService iUserService;

    @Override
    public R getOrderList(PageInfoVo pageInfoVo) {
        String token = request.getHeader("token");
        if(token==null){
            return R.ERROR(500,"请先登录");
        }
        Page<TbOrder> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = body.get("userId", Integer.class);

        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(pageInfoVo.getKeyWord())){
            wrapper.lambda().like(TbOrder::getProdInfo,pageInfoVo.getKeyWord())
                    .or()
                    .like(TbOrder::getOrderId,pageInfoVo.getKeyWord());
        }
        if(pageInfoVo.getTypeId()!=null){
            wrapper.lambda().eq(TbOrder::getOrderType,pageInfoVo.getTypeId());
        }
        if(pageInfoVo.getOrderStatus()!=null){
            wrapper.lambda().eq(TbOrder::getOrderStatus,pageInfoVo.getOrderStatus());
        }
        wrapper.lambda().orderByDesc(TbOrder::getCreateTime);
        Page<TbOrder> tbOrderPage = tbOrderMapper.selectPage(page, wrapper);

        redisTemplate.opsForValue().set("order-"+userId,JSON.toJSONString(tbOrderPage.getRecords()));

        return R.OK(tbOrderPage);
    }

    @Override
    public void excelPage(Integer userId) {
        ExcelUtil<TbOrder> excelUtil = new ExcelUtil<>(TbOrder.class);
        String s = redisTemplate.opsForValue().get("order-" + userId);
        excelUtil.exportExcel(response,JSON.parseArray(s,TbOrder.class),"订单列表");
    }

    @Override
    public R getProdInfo() {
        List<TbProdInfo> tbProdInfos = tbProdInfoMapper.selectList(null);
        return R.OK(tbProdInfos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R addOrder(List<TbProdInfo> tbProdInfoList) {
        String token = request.getHeader("token");
        if (token == null) {
            return R.ERROR(500,"请先登录");
        }
        Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = body.get("userId", Integer.class);
        String userName = body.get("userName", String.class);
        BigDecimal totalAmount = new BigDecimal("0");
        StringBuilder prodNames = new StringBuilder();

        RLock lock = redissonClient.getLock("order-lock");
        try {
            lock.lock();

            for (TbProdInfo tbProdInfo : tbProdInfoList) {
                TbProdInfo prodInfo = tbProdInfoMapper.selectById(tbProdInfo.getInfoId());
                if (tbProdInfo.getBuyNum() > prodInfo.getProdStock()) {
                    return R.ERROR(500,"库存不足");
                }
                prodInfo.setProdStock(prodInfo.getProdStock() - tbProdInfo.getBuyNum());
                tbProdInfoMapper.updateById(prodInfo);

                totalAmount = totalAmount.add(tbProdInfo.getProdPrice().multiply(new BigDecimal(tbProdInfo.getBuyNum())));

                if (prodNames.length() > 0) {
                    prodNames.append(",");
                    prodNames.append(tbProdInfo.getProdName());
                } else {
                    prodNames.append(tbProdInfo.getProdName());
                }
            }
        } finally {
            lock.unlock();
        }


        TbOrder tbOrder = new TbOrder();

        //雪花算法生成订单编号
        long id = IdUtil.getSnowflake(1, 1).nextId();
        tbOrder.setOrderNo(id + "");
        tbOrder.setOrderType(1);
        tbOrder.setOrderStatus(0);
        tbOrder.setCreateTime(new Date());
        tbOrder.setUserId(userId);
        tbOrder.setOrderAmount(totalAmount);
        tbOrder.setProdInfo(prodNames.toString());
        tbOrder.setCreateBy(userName);
        tbOrderMapper.insert(tbOrder);

        for (TbProdInfo tbProdInfo : tbProdInfoList) {
            TbOrderDetail tbOrderDetail = new TbOrderDetail();
            tbOrderDetail.setOrderId(tbOrder.getOrderId());
            tbOrderDetail.setBuyNum(tbProdInfo.getBuyNum());
            tbOrderDetail.setProdId(tbProdInfo.getProdId());
            tbOrderDetail.setBuyPrice(tbProdInfo.getProdPrice());
            tbOrderDetail.setInfoId(tbProdInfo.getInfoId());
            tbOrderDetail.setCreateBy(userName);
            tbOrderDetail.setCreateTime(new Date());
            tbOrderDetailMapper.insert(tbOrderDetail);
        }

        TbOrderRecord tbOrderRecord = new TbOrderRecord();
        tbOrderRecord.setOrderId(tbOrder.getOrderId());
        tbOrderRecord.setOptRecord("用户创建订单");
        tbOrderRecord.setCreateTime(new Date());
        tbOrderRecord.setCreateBy(userName);
        tbOrderRecordMapper.insert(tbOrderRecord);
        return R.OK();
    }

    @Override
    public R getOrderInfoById(Integer orderId) {
        TbOrder tbOrder = tbOrderMapper.selectById(orderId);
        if(tbOrder==null){
            return R.ERROR(500,"订单不存在");
        }

        R r = iUserService.getUserInfoByUserId(tbOrder.getUserId());
        if(r.getCode()!=200){
            return r;
        }
        String s = JSON.toJSONString(r.getData());
        TbUser tbUser = JSON.parseObject(s, TbUser.class);
        tbOrder.setTbUser(tbUser);

        List<OrderDetailVo> prodInfo = tbOrderDetailMapper.getProdInfoByOrderId(tbOrder.getOrderId());
        tbOrder.setOrderDetailVoList(prodInfo);

        List<TbOrderRecord> orderRecordByOrderId = tbOrderRecordMapper.getOrderRecordByOrderId(tbOrder.getOrderId());
        tbOrder.setOrderRecordList(orderRecordByOrderId);

        return R.OK(tbOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteBatchOrder(List<Integer> ids) {
        tbOrderMapper.deleteBatchIds(ids);

        tbOrderDetailMapper.delete(new QueryWrapper<TbOrderDetail>().lambda().in(TbOrderDetail::getOrderId,ids));

        tbOrderRecordMapper.delete(new QueryWrapper<TbOrderRecord>().lambda().in(TbOrderRecord::getOrderId,ids));

        return R.OK();
    }

    @Override
    public R getOrderRecord() {
        QueryWrapper<TbOrderRecord> wrapper = new QueryWrapper<>();
        wrapper.lambda().orderByAsc(TbOrderRecord::getCreateTime);
        List<TbOrderRecord> tbOrderRecords = tbOrderRecordMapper.selectList(wrapper);
        return R.OK(tbOrderRecords);
    }
}




